package services

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"go-tool/components"
	"go-tool/db"
	"go-tool/db/orm_iray_proxy"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"time"
)

type JobInfo struct {
}

func (e *JobInfo) ErgodicFiles() {
	path := "./iray_db_back"
	err := filepath.Walk(path, func(path string, f os.FileInfo, err error) error {
		if f == nil {
			return err
		}
		if f.IsDir() {
			return nil
		}
		fmt.Println(path)
		fmt.Println(path[strings.Index(path, "-")+1 : strings.Index(path, ".db")])
		//insertDb(path)
		return nil
	})
	if err != nil {
		fmt.Printf("filepath.Walk() returned %v\n", err)
	}
}

func insertDb(path string) {
	ip := path[strings.Index(path, "-")+1 : strings.Index(path, ".db")]
	db.InitDbLite(path)
	sqlStr := `SELECT Name job_id, DateCreated start_time, DateCreated submit_time, DateModified finished_time,
				Height as height, Width as width, Priority as priority,MaxIterations max_iterations, b.RenderTime render_time
				from jobs 
				LEFT JOIN job_snapshots b on b.JobID=jobs.UUID
				where b.RenderTime>0`
	var jobs []orm_iray_proxy.JobInfo
	num := 0
	err := db.DbLite.Select(&jobs, sqlStr)
	if err != nil {
		fmt.Printf("query failed, err:%v\n", err)
		return
	}
	for i := 0; i < len(jobs); i++ {
		jobs[i].Ip.String = ip
		jobs[i].Ip.Valid = true
		if jobs[i].UpdateIp() {
			num++
		}
	}
	fmt.Println("job num: ", len(jobs), " success: ", num)
}

//导入es
func (e *JobInfo) InsertEs(obj JobIrayObj) (err error) {
	components.EsClient.Index = "job"
	components.EsClient.Type = "log"
	put, err := components.EsClient.Push(obj)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Indexed tweet %s to index s%s, type %s\n", put.Id, put.Index, put.Type)
	return
}

func (e *JobInfo) JobEach() (count int) {
	var wg sync.WaitGroup
	var lock sync.Mutex
	count = 0
	DbJob := orm_iray_proxy.JobInfo{}
	limit := 5000
	offset := 0
	for {
		fmt.Println("db search")
		rows, err := DbJob.Query(offset, limit)
		wg.Wait()
		fmt.Println("start")
		if err != nil {
			fmt.Println("err: ", err)
			return
		}
		if len(rows) == 0 {
			return
		}
		wg.Add(1)
		go func(rows []orm_iray_proxy.JobInfo) {
			for i := 0; i < len(rows); i++ {
				lock.Lock()
				obj := e.DbJobInfoToJobObj(rows[i])
				err = e.InsertEs(obj)
				if err == nil {
					count++
				} else {
					fmt.Println("err: ", err)
				}
				if count%100 == 0 {
					fmt.Println("id: ", count)
				}
				lock.Unlock()
			}
			wg.Done()
		}(rows)
		offset = offset + limit
	}
	return
}

func (e *JobInfo) DbJobInfoToJobObj(info orm_iray_proxy.JobInfo) (obj JobIrayObj) {
	obj = JobIrayObj{
		Timestamp:      info.FinishedTime.Time.UTC(),
		RenderedTime:   info.FinishedTime.Time.Local().Format("2006-01-02 15:04:05"),
		JobID:          info.JobId,
		FinishedTime:   info.FinishedTime.Time.Local().Format("2006-01-02 15:04:05"),
		TotalCost:      info.FinishedTime.Time.Local().Unix() - info.SubmitTime.Time.Unix(),
		StartTime:      time.Unix(info.FinishedTime.Time.Unix()-int64(info.RenderTime.Float64), 0).Local().Format("2006-01-02 15:04:05"), //减去渲染时长 rendercost
		Ts:             info.FinishedTime.Time.Local(),
		Height:         info.Height,
		LogTopic:       "cloud-rendering-stat",
		RenderCost:     int64(info.RenderTime.Float64),
		WaitRenderCost: info.FinishedTime.Time.Local().Unix() - info.SubmitTime.Time.Unix() - int64(info.RenderTime.Float64),
		UploadCost:     0,
		Msg:            "irayJobStat",
		Priority:       info.Priority,
		HostIP:         info.Ip.String,
		Width:          info.Width,
		MaxIterations:  info.MaxIterations,
		SubmitTime:     info.SubmitTime.Time.Local().Format("2006-01-02 15:04:05"),
		Level:          "info",
		Success:        true,
	}
	return
}

func (e *JobInfo) JobEachConstructScene() (count int) {
	id := 0
	DbJob := orm_iray_proxy.JobInfo{}
	limit := 5000
	for {
		rows, err := DbJob.QueryByConstruct(int64(id), int64(id), int64(limit))
		fmt.Println("start")
		if err != nil {
			fmt.Println("err: ", err)
			return
		}
		if len(rows) == 0 {
			fmt.Println("rows len : ", len(rows))
			return
		}
		for i := 0; i < len(rows); i++ {
			if rows[i].InsertByConstructScene() {
				count++
				id = rows[i].Id
				fmt.Println("id: ", id)
			}
		}
	}
	return
}

func (e *JobInfo) JobEachConstructRequest() (count int) {
	id := 0
	DbJob := orm_iray_proxy.JobInfo{}
	limit := 5000
	offset := 0
	for {
		rows, err := DbJob.QueryByConstructResult(0, 0, int64(offset), int64(limit))
		if err != nil {
			fmt.Println("err: ", err)
			return
		}
		if len(rows) == 0 {
			fmt.Println("rows len : ", len(rows))
			return
		}
		for i := 0; i < len(rows); i++ {
			if rows[i].InsertByConstructResult() {
				count++
				id = rows[i].Id
				fmt.Println("id: ", id)
			}
		}
		offset = offset + limit
	}
	return
}
